<template>
  <div>out1: {{ out1 }}</div>
  <div>out2: {{ out2 }}</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
type RejectMethod = (reason?: any) => void

function buildCancelablePromise<T>(p: Promise<T>) {
  let outReject: undefined | RejectMethod
  const rejectPromise = new Promise((_, reject) => {
    outReject = reject
  })
  function cancel() {
    if (outReject) outReject('取消Promise')
  }
  const cancelablePromise = Promise.race([p, rejectPromise])
  return { cancelablePromise, cancel }
}
const out1 = ref()
const out2 = ref()
;(() => {
  const p = new Promise(resolve => {
    setTimeout(() => {
      resolve(666)
    }, 3000)
  })

  const { cancelablePromise, cancel } = buildCancelablePromise(p)
  cancelablePromise
    .then(
      ret => {
        out1.value = `then的resolve回调函数执行: ${ret}`
      },
      e => {
        out1.value = `then的reject回调函数执行: ${e}`
      }
    )
    .catch(e => {
      out1.value = `catch回调函数执行: ${e}`
    })
  cancel()

  const { cancelablePromise: cancelablePromise2, cancel: cancel2 } = buildCancelablePromise(p)
  cancelablePromise2
    .then(
      ret => {
        out2.value = `then的resolve回调函数执行: ${ret}`
      },
      e => {
        out2.value = `then的reject回调函数执行: ${e}`
      }
    )
    .catch(e => {
      out2.value = `catch回调函数执行: ${e}`
    })
})()
</script>

<style scoped></style>
